home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / Moscow ML 1.42 / src / mosmllib / String.sml < prev    next >
Encoding:
Text File  |  1997-08-18  |  4.1 KB  |  142 lines  |  [TEXT/R*ch]

  1. (* String -- 1994-12-10, 1995-11-07 *)
  2.  
  3. local 
  4.     type char = Char.char;
  5.     prim_val sub_      : string -> int -> char         = 2 "get_nth_char";
  6.     prim_val mkstring_ : int -> string                 = 1 "create_string";
  7.     prim_val update_   : string -> int -> char -> unit = 3 "set_nth_char";
  8.     prim_val strcmp_   : string -> string -> int       = 2 "compare_strings";
  9.     prim_val blit_     : string -> int -> string -> int -> int -> unit 
  10.                                                        = 5 "blit_string";
  11.  
  12.     fun (f o g) x = f (g x);
  13. in
  14.  
  15. type string = string
  16. val maxSize = Strbase.maxlen
  17. val size = size
  18.  
  19. fun sub(s, i) = 
  20.     if i<0 orelse i >= size s then raise Subscript
  21.     else sub_ s i;
  22.  
  23. fun concat strs =
  24.     let fun acc [] len       = len
  25.           | acc (v1::vr) len = acc vr (size v1 + len)
  26.         val len = acc strs 0
  27.         val newstr = if len > maxSize then raise Size else mkstring_ len 
  28.         fun copyall to []       = ()
  29.           | copyall to (v1::vr) = 
  30.             let val len1 = size v1
  31.             in blit_ v1 0 newstr to len1; copyall (to+len1) vr end
  32.     in copyall 0 strs; newstr end;
  33.  
  34. val op ^ = op ^;
  35.  
  36. fun str c = 
  37.     let val newstr = mkstring_ 1
  38.     in update_ newstr 0 c; newstr end;
  39.  
  40. fun implode cs = 
  41.   let val n = List.length cs
  42.       val newstr = if n > maxSize then raise Size else mkstring_ n
  43.       fun init []      i = ()
  44.         | init (c::cr) i = (update_ newstr i c; init cr (i+1))
  45.   in (init cs 0; newstr) end;
  46.  
  47. fun extract (s, i, slicelen) =
  48.     let val n = case slicelen of NONE => size s - i | SOME n => n
  49.     val newstr = if i<0 orelse n<0 orelse n>size s-i then raise Subscript
  50.              else mkstring_ n
  51.     in blit_ s i newstr 0 n; newstr end;
  52.  
  53. fun substring (s, i, n) = extract(s, i, SOME n);
  54.  
  55. fun explode s =
  56.     let fun h j res = if j<0 then res
  57.               else h (j-1) (sub_ s j :: res)
  58.     in h (size s - 1) [] end;
  59.  
  60. fun compare (s1, s2) = 
  61.     (case strcmp_ s1 s2 of
  62.          ~2 => LESS
  63.        | ~1 => LESS
  64.        |  0 => EQUAL
  65.        |  1 => GREATER
  66.        |  2 => GREATER
  67.        |  _ => raise Fail "internal error: String.compare");
  68.  
  69. fun collate cmp (s1, s2) =
  70.     let val n1 = size s1 
  71.     and n2 = size s2
  72.     val stop = if n1 < n2 then n1 else n2
  73.     fun h j = (* At this point s1[0..j-1] = s2[0..j-1] *)
  74.         if j = stop then if      n1 < n2 then LESS
  75.                              else if n1 > n2 then GREATER
  76.                              else                 EQUAL
  77.         else
  78.         case cmp(sub_ s1 j, sub_ s2 j) of
  79.             LESS    => LESS
  80.           | GREATER => GREATER
  81.           | EQUAL   => h (j+1)
  82.     in h 0 end;
  83.  
  84. fun translate f s = 
  85.     Strbase.translate f (s, 0, size s);
  86.  
  87. fun tokens p s = 
  88.     List.map substring (Strbase.tokens p (s, 0, size s));
  89.  
  90. fun fields p s = 
  91.     List.map substring (Strbase.fields p (s, 0, size s));
  92.  
  93. fun isPrefix s1 s2 = 
  94.     let val n1 = size s1 
  95.     and n2 = size s2
  96.     val stop = if n1 < n2 then n1 else n2
  97.     fun h j = (* At this point s1[0..j-1] = s2[0..j-1] *)
  98.         j = stop orelse sub_ s1 j = sub_ s2 j andalso h (j+1)
  99.     in n1 <= n2 andalso h 0 end;
  100.  
  101. fun foldl f e s = 
  102.     let val stop = size s
  103.     fun h j res = if j>=stop then res 
  104.               else h (j+1) (f (sub_ s j, res))
  105.     in h 0 e end;
  106.  
  107. fun foldr f e s = 
  108.     let fun h j res = if j<0 then res 
  109.                       else h (j-1) (f (sub_ s j, res))
  110.     in h (size s - 1) e end;
  111.  
  112. fun find p s = 
  113.     let val stop = size s
  114.     fun h j = if j>=stop then NONE 
  115.           else if p (sub_ s j) then SOME j
  116.           else h (j+1) 
  117.     in h 0 end;
  118.  
  119. fun fromString s =
  120.     let fun getc i = if i < size s then SOME (sub_ s i, i+1) else NONE
  121.     fun h src res = 
  122.         case getc src of
  123.         NONE              => SOME (implode(List.rev res))
  124.           | SOME(#"\\", src1) => 
  125.             (case Strbase.fromMLescape getc src1 of
  126.              NONE          => NONE
  127.                | SOME(c, src2) => h src2 (c :: res))
  128.           | SOME(c, src1)     => h src1 (c :: res)
  129.     in h 0 [] end;
  130.     
  131. fun toString s = Strbase.translate Strbase.toMLescape (s, 0, size s);
  132.  
  133. fun fromCString s = Strbase.fromCString s
  134.  
  135. fun toCString s = Strbase.translate Strbase.toCescape (s, 0, size s)
  136.  
  137. val op <  = op <  : string * string -> bool;
  138. val op <= = op <= : string * string -> bool;
  139. val op >  = op >  : string * string -> bool;
  140. val op >= = op >= : string * string -> bool;
  141. end
  142.